package meatslope2.gameengine.scene;

import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

import javax.microedition.khronos.opengles.GL10;

import meatslope2.application.GameApplication;
import meatslope2.application.R;
import meatslope2.gameengine.gameobjects.GameObject;
import meatslope2.gameengine.gameobjects.Player;
import meatslope2.gameengine.helpers.GLHelper;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;

//TODO: Optimize later, if needed
//TODO: draw in order of priority
//TODO: get rid of linked lists?  Will look at when enemies/shooting get involved
public class Scene 
{
	private final List<GameObject> deadObjects = new LinkedList<GameObject>();
	private final List<GameObject> aliveObjects;
	private final TileWorld tileWorld;
	
	private final GameApplication gameApplication;
	private Player player;
	
	public Player getPlayer()
	{
		return this.player;
	}
	
	public TileWorld getTileWorld()
	{
		return this.tileWorld;
	}
	
	private Scene(GameApplication game, Player player, GameObject[] gameObjectArray, TileWorld tileWorld)
	{
		if(game == null)
			throw new IllegalArgumentException("game cannot be null");
		
		//TODO: change this garbage
		if(gameObjectArray == null)
			this.aliveObjects = new LinkedList<GameObject>();
		else
			this.aliveObjects = Arrays.asList(gameObjectArray);
		
		this.gameApplication = game;
		this.player = player;
		this.tileWorld = tileWorld;
	}
	
	public void update()
	{
        for (int i = 0; i < this.aliveObjects.size(); i++)
        {
        	final GameObject object = this.aliveObjects.get(i);
        	
        	//Swap to dead pool if dead
        	if(object.isDead())
        	{
        		this.aliveObjects.remove(object);
        		this.deadObjects.add(object);
        	}
        	else
        		object.update();
        }
	}
	
	//TODO: Drawing in order - should change to drawing by priority member in gameobject
	public void draw(GL10 pGL)
	{
        pGL.glMatrixMode(GL10.GL_MODELVIEW);
                
        for (int i = 0; i < this.aliveObjects.size(); i++)
        {	
        	final GameObject enemy = this.aliveObjects.get(i);
        	enemy.draw(pGL);
        }
        
        tileWorld.draw(pGL);
	}
	
	public void loadBitmaps(GL10 pGL)
	{
       if (aliveObjects == null) 
    	   return;
       
       // Load our texture and set its texture name on all sprites.
       
       // To keep this sample simple we will assume that sprites that share
       // the same texture are grouped together in our sprite list. A real
       // app would probably have another level of texture management, 
       // like a texture hash.
       
       int lastLoadedResource = -1;
       int lastTextureId = -1;
       
       for (int i = 0; i < aliveObjects.size(); i++)
       {
    	   GameObject.Sprite sprite = aliveObjects.get(i).getSprite();
           int resource = sprite.getResourceId();
           if (resource != lastLoadedResource) 
           {
               GLHelper.loadBitmap(gameApplication, pGL, sprite);
               
               lastLoadedResource = resource;
               lastTextureId = sprite.getTextureName();
           }
           sprite.setTextureName(lastTextureId);
       }
	}
	
	public static class Factory 
	{
	    //TODO: nuke this sample
	    public static Scene generateSampleLevel1(GameApplication gameApplication)
	    {
	        // Allocate space for the robot sprites + one background sprite.
	        GameObject[] gameObjectArray = new GameObject[2];    
	       
	        //Get background image
	        BitmapDrawable backgroundImage = (BitmapDrawable)gameApplication.getResources().getDrawable(R.drawable.background);
	        Bitmap backgoundBitmap = backgroundImage.getBitmap();
	        
	        //Get height, width of background image
	        final int width = backgoundBitmap.getWidth();
	        final int height = backgoundBitmap.getHeight();
	        
	        //create background gameobject with background image, assign to gameobject array
	        GameObject background = new GameObject(R.drawable.background, width, height);       
	        gameObjectArray[0] = background;
	        
	        //create player
	        Player player = new Player();
	        player.getPosition().add(0, 128);
	        gameObjectArray[1] = player;
	        
	        //create tile world
	        TileWorld tileWorld = TileWorld.Factory.buildLevel1();
	        
	        Scene scene = new Scene(gameApplication, player, gameObjectArray, tileWorld);
	        return scene;
	    }
	}
}
